﻿using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using MiniFox.Data;
using MiniFox.Infrastructure;
using MiniFox.Utility;
using MiniFox.Web.Infrastructure;
using System.ComponentModel.DataAnnotations;
using System.Data;

namespace MiniFox.Platform.Web
{
    /// <summary>
    /// 
    /// </summary>
    public abstract class DataControllerBase : MvcControllerBase
    {
        /// <summary>
        /// 
        /// </summary>
        protected abstract DataSourceFactory Component { get; }
        
        /// <summary>
        /// 
        /// </summary>
        /// <param name="name"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="sortFields"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        protected virtual PagedResultObject<ViewTable> PagedQuery(string name, int pageIndex, int pageSize, IDictionary<string, bool> sortFields, object parameters)
        {
            DataSourceFactory factory = this.Component;
            var dataQuery = factory.GetDataCommand(name);
            if (dataQuery == null)
                return new PagedResultObject<ViewTable>(0, pageIndex, pageSize);
            DataTable dataTable = new DataTable(name);
            var total = dataQuery.FillDataTable(dataTable, pageIndex, pageSize, sortFields, parameters.ToDictionary());
            var result = new PagedResultObject<ViewTable>(total, pageIndex, pageSize);
            result.Result = dataTable.ConvertToViewTable() ;
            return result;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="name"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        protected virtual ResultObject<ViewTable> DataQuery(string name, object parameters)
        {
            DataSourceFactory factory = this.Component;
            var dataQuery = factory.GetDataCommand(name);
            if (dataQuery == null)
                return new ResultObject<ViewTable>(0);
            DataTable dataTable = new DataTable(name);
            dataQuery.FillDataTable(dataTable, parameters.ToDictionary());
            var result = new ResultObject<ViewTable>(dataTable.Rows.Count);
            result.Result = dataTable.ConvertToViewTable();
            return result;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="name"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        protected virtual object ObjectQuery(string name, object parameters)
        {
            DataSourceFactory factory = this.Component;
            var objectQuery = factory.GetDataCommand(name);
            if (objectQuery == null)
                return null;
            return objectQuery.ExecuteObjectQuery(parameters.ToDictionary());
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="name"></param>
        /// <param name="nodeKey"></param>
        /// <param name="superKey"></param>
        /// <param name="sortKey"></param>
        /// <param name="groupKey"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        protected virtual TreeResultObject TreeDataQuery(string name, string nodeKey, string superKey, string sortKey, string groupKey, object parameters)
        {
            DataSourceFactory factory = this.Component;
            var dataQuery = factory.GetDataCommand(name);
            if (dataQuery == null)
                return null;
            var result = dataQuery.ExecuteDataQuery(parameters.ToDictionary());
            return new TreeResultObject(result.Data, nodeKey, superKey, sortKey, groupKey);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="name"></param>
        /// <param name="query"></param>
        /// <returns></returns>
        [HttpPost]
        public virtual Response<PagedResultObject<ViewTable>> PagedQuery([FromRoute, Required] string name, [FromBody]PagedQueryObject query)
        {
            var result = PagedQuery(name, query.PageIndex, query.PageSize, query.SortFields, query.Parameters);
            var response = result.CreateResponse();
            return response;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="name"></param>
        /// <param name="query"></param>
        /// <returns></returns>
        [HttpPost]
        public virtual Response<ResultObject<ViewTable>> DataQuery([FromRoute, Required] string name, [FromBody] QueryObject query)
        {
            var result = DataQuery(name, query.Parameters);
            var response = result.CreateResponse();
            return response;
        }
        /// <summary>
        /// 树查询ss
        /// </summary>
        /// <param name="name">查询名称</param>
        /// <param name="query">查询对象</param>
        /// <returns></returns>
        [HttpPost]
        public virtual Response<TreeResultObject> TreeQuery([FromRoute, Required] string name, [FromBody] TreeQueryObject query)
        {
            var result = TreeDataQuery(name, query.NodeKey, query.SuperKey, query.SortKey, query.GroupKey, query.Parameters);
            var response = result.CreateResponse();
            return response;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="name"></param>
        /// <param name="query"></param>
        /// <returns></returns>
        [HttpPost]
        public virtual Response<object> ObjectQuery([FromRoute, Required] string name, [FromBody] QueryObject query)
        {
            var result = this.ObjectQuery(name, query.Parameters);
            var response = result.CreateResponse();
            return response;
        }
        /// <summary>
        /// 批量操作更新
        /// </summary>
        /// <param name="name"></param>
        /// <param name="dataItems"></param>
        /// <returns></returns>
        [HttpPost]
        public virtual Response<int> DataOperate([FromRoute, Required] string name, [FromBody] object[] dataItems)
        {
            DataSourceFactory factory = this.Component;
            var dataOperation = factory.GetDataCommand(name); 
            int rowCount = 0;
            if (dataOperation != null)
                rowCount = dataOperation.ExecuteOperation(dataItems);
            var response = rowCount.CreateResponse();
            return response;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        [HttpGet]
        public virtual Response<ResultObject<ViewTable>> DataQuery([FromRoute, Required] string name)
        {
            var parameters = Request.Query.ToDictionary();
            var result = this.DataQuery(name, parameters);
            var response = result.CreateResponse();
            return response;
        }
        /// <summary>
        /// api: data/objectquery/{name}
        /// 查询并返回单个对象
        /// </summary>
        /// <param name="name">查询名</param>
        /// <returns></returns>
        [HttpGet]
        public virtual Response<object> ObjectQuery([FromRoute, Required] string name)
        {
            var parameters = Request.Query.ToDictionary();
            var result = this.ObjectQuery(name, parameters);
            var response = result.CreateResponse();
            return response;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="name"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="sortField"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        [HttpGet]
        public virtual Response<PagedResultObject<ViewTable>> PagedQuery([FromRoute, Required] string name, [FromQuery, Required] int? pageIndex, [FromQuery, Required] int? pageSize, [FromQuery, Required] string sortField, object data)
        {
            var parameters = data.ToDictionary();
            if (parameters == null || parameters.Count <= 0)
            {
                parameters = null;
            }
            var sortFields = new Dictionary<string, bool>();
            sortFields.Add(sortField, false);
            var result = this.PagedQuery(name, pageIndex ?? 1, pageSize ?? 20, sortFields, parameters);
            return result.CreateResponse();
        }
        /// <summary>
        /// 树查询
        /// </summary>
        /// <param name="name">查询名称</param>
        /// <param name="nodeKey">ID字段名</param>
        /// <param name="superKey">父级ID字段名</param>
        /// <param name="groupKey">组字段名</param>
        /// <param name="sortKey">排序字段名</param>
        /// <returns>返回树型结构集合</returns>
        [HttpGet]
        public virtual Response<TreeResultObject> TreeQuery([FromRoute, Required] string name, [FromQuery, Required] string nodeKey, [FromQuery, Required] string superKey, [FromQuery, Required] string groupKey, [FromQuery, Required] string sortKey)
        {
            var result = this.TreeDataQuery(name, nodeKey, superKey, sortKey, groupKey, null);
            var response = result.CreateResponse();
            return response;
        }
    }

}
